package com.ywj.interview.thread.foundation;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class StateTransition {
    private final static Logger LOG = LoggerFactory.getLogger(StateTransition.class);

    /*
    t1 running ...
    t2 running ...
     */
    private static void testNewRunnableTerminated() {
        Thread t1 = new Thread(() -> {
            System.out.println("t1 running ...");
        }, "t1");
        Thread t2 = new Thread(() -> {
            System.out.println("t2 running ...");
        }, "t2");

        t1.start();
        t2.start();
    }

    /*
    running ...
    before sync ...
    in sync ...
     */
    private static void testBlocked() {
        Thread t1 = new Thread(() -> {
            System.out.println("before sync ...");
            synchronized(StateTransition.class) {
                System.out.println("in sync ...");
            }
        }, "t1");

        t1.start();
        synchronized(StateTransition.class) {
            System.out.println("running ...");
        }
    }

    /*
1.synchronized (StateTransition.class)  报如下错。synchronized (st)  正常输出before waiting ...，且线程为停止
before waiting ...
Exception in thread "main" Exception in thread "t1" java.lang.IllegalMonitorStateException
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:502)
	at com.ywj.interview.thread.StateTransition.lambda$testWaiting$3(StateTransition.java:65)
	at java.lang.Thread.run(Thread.java:750)
java.lang.IllegalMonitorStateException
	at java.lang.Object.notify(Native Method)
	at com.ywj.interview.thread.StateTransition.testWaiting(StateTransition.java:74)
	at com.ywj.interview.thread.StateTransition.main(StateTransition.java:98)

     */
    private static void testWaiting() {
        Object locker = new Object();
        Thread t1 = new Thread(() -> {
            synchronized (locker) {
                System.out.println("before waiting ...");
                try {
                    locker.wait();
                } catch(InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "t1");

        t1.start();
        synchronized (locker) {
            locker.notify();
        }
    }

    /* 输出以下，且会正常退出
    running ...
     */
    private static void testTimedWaiting() {
        Thread t1 = new Thread(() -> {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("running ...");
        }, "t1");
        t1.start();
    }

    private static void testJoin() {
        Thread t1 = new Thread(() -> {
            System.out.println("t1");
        }) ;
        Thread t2 = new Thread(() -> {
//            try {
//                t1.join();  // 加入线程t1，只有t1线程执行完毕以后，再次执行该线程
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
            System.out.println("t2");
        });
        Thread t3 = new Thread(() -> {
//            try {
//                t2.join();  // 加入线程t2，只有t2线程执行完毕以后，再次执行该线程
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
            System.out.println("t3");
        });
        //启动线程
        t1.start();
        t2.start();
        t3.start();
    }

    public static void main(String[] args) {
//        testNewRunnableTerminated();

//        testBlocked();

//        testWaiting();

//        testTimedWaiting();

        testJoin();
    }
}

